package poker;

import javax.swing.*;
import javax.xml.transform.Result;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.Scanner;

public class TableGui extends JFrame {
	boolean second = false;
	/**
	 * 
	 */
	Wait w = new Wait();
	private static final long serialVersionUID = 1L;
	final Table table;

	final HandGui hand[] = new HandGui[4];
	final PlayerGui players[] = new PlayerGui[4];
	boolean PlayerStatus[] = new boolean[4]; // 1-Human 0-Player
	public JTextArea tablePoolGui;
	  Random generator=new Random();
	JTextArea CashPlayer[] = new JTextArea[4];
	JTextArea PlayerName[] = new JTextArea[4];
	int i, j;
	Color background = new Color(0, 128, 128);
	//boolean PlayerMove[] = new boolean[4]; //0-entryFeeTurn,1-betTurn, 2-exchangeTurn,3-evaluate turn;4-winner turn;5-displayranking
	/**
	 * Launch the application.
	 */
	
	  /** RESETOWANIE WSZYSTKICH USTAWIEN. */
	 private void resetAllSettings(){
	    table.numberOfPlayers=0; table.numberOfHumanPlayers=0; table.numberOfChips=0; table.entryFee=0; table.tablePool=0; table.numberOfActivePlayers=0; table.betPosition=generator.nextInt(5); table.enoughPlayers=false; table.playedAllIn=false;
		for(int i=0;i<4;i++){table.players[i]=null; table.hands[i]=null; table.playersChips[i]=0; table.playersWins[i]=0; table.playersBets[i]=0; table.playersActivity[i]=0;
		PlayerStatus[i]=false;}
	  }

	  /** WCZYTYWANIE LICZBY GRACZY. */
	/* private void loadNumberOfPlayers(){
		table.numberOfPlayers=input;
	  } */

	  /** WCZYTYWANIE LICZBY GRACZY-LUDZI. */
	  /*private void loadNumberOfHumanPlayers(){
	    Scanner keyboard=new Scanner(System.in);
		try{
	      do{System.out.print("Number of human players (0-" + numberOfPlayers + "): "); input=keyboard.nextInt();} while((input<0)||(input>numberOfPlayers));
		} catch (Exception e){System.out.println("INVALID INPUT"); System.exit(0);} // DLA NIEPOPRAWNEJ WARTOSCI PRZERYWAMY DZIALANIE. 
		numberOfHumanPlayers=input;
	  }*/

	  /** UTWORZENIE GRACZY. */
	  private void createPlayers(){
		  System.out.println("Wywolana zostala metoda createPlayers()");
		  String Name;
		  for (i = 0 ; i < table.numberOfHumanPlayers; i++ ){
			    table.players[i]=null;
				Name="Human [" + i + "]";
				table.players[i]=new Human(Name);
				table.playersActivity[i]=1;
				table.playersChips[i]=table.numberOfChips;
				table.numberOfActivePlayers=+1;
				PlayerStatus[i]=true;
				System.out.println("Stworzylem gracza" +table.players[i].getName());
			}
			for (; i< table.numberOfPlayers; i++, j++) {
				 table.players[i]=null;
				Name="Bot [" + i + "]";
				table.players[i]=new Bot(Name);
				table.playersActivity[i]=1;
				table.playersChips[i]=table.numberOfChips;
				table.playersActivity[i]=1;
				table.numberOfActivePlayers=+1;
				System.out.println("Stworzylem gracza" +table.players[i].getName());
			}
			for (i = 0; i<table.numberOfHumanPlayers;i++){
				players[i]= new HumanGui("Human ["+i+"]",i);
				getContentPane().add(players[i]);
			}
			for (; i<table.numberOfPlayers;i++){
				players[i]= new BotGui(i);
				getContentPane().add(players[i]);
			}
			System.out.println("Zakonczona metoda createPlayers()");
	  }
	   
	 
	
	  /** WYRZUCANIE GRACZY BEZ ZETONOW, SPRAWDZANIE LICZBY POZOSTALYCH GRACZY. */
	  /** KONTROLA KOLEJKI DO NASTEPNEJ LICYTACJI, RESETOWANIE ZMIENNEJ playedAllIn. */
	  void checkPlayers(){
		 System.out.println("Wywolana metoda checkPlayers()") ;
		for(i=0;i<table.numberOfPlayers;i++){
			table.playersActivity[i]=1;
		}
	    for(i=0;i<table.numberOfPlayers;i++){
	    	if((table.playersChips[i]-1)<table.entryFee){
	    		table.playersActivity[i]=0;
	    	}
	    }
		for(i=0;i<table.numberOfPlayers;i++){if(table.playersActivity[i]==1){table.numberOfActivePlayers+=1;}}
		if(table.numberOfActivePlayers<2){table.enoughPlayers=false;}
		else{table.enoughPlayers=true;}
	    if(table.betPosition<3){table.betPosition++;}
		else{table.betPosition=0;}
	    table.playedAllIn=false;
		 System.out.println("Sprawdzilem "+table.numberOfPlayers+" graczy. Mozliwosc gry:"+table.enoughPlayers );
		 System.out.println("Zakonczona metoda checkPlayers()") ;
	  }

	  /** TURA WPISOWEGO. */
	  void entryFeeTurn(){
		for(int i=0;i<table.numberOfPlayers;i++){
		  if(table.playersActivity[i]==1){table.playersBets[i]+=table.entryFee; table.tablePool+=table.entryFee; table.playersChips[i]-=table.entryFee;}
		}
		System.out.println("entryTurn" );
	  }

	  /** UTWORZENIE RAK GRACZY. */
	  void createHands(){
		System.out.println("Wywoalana metoda createHands()" );
		for(i=0;i<4;i++){table.hands[i]=null;}
	    for(i=0;i<table.numberOfPlayers;i++){
	    	if(table.playersActivity[i]==1) {
	    		table.hands[i]=new Hand(table.deck);
		    	hand[i]= new HandGui(table.hands[i]);
				players[i].add(hand[i]);
				table.hands[i].display();
	    	}
	    }
	    System.out.println("Zakonczona metoda createHands()" );
	   }

	  /** TURA WYSWIETLANIA KART GRACZY. */
	  void displayTurn(){
		for(int i=0;i<table.numberOfPlayers;i++){
		  if(table.playersActivity[i]==1){
		    System.out.println(table.players[i].getName());
		   table.hands[i].display();
		    System.out.println();
	      }
		}
		
	  }

	  /** TURA WYMIANY KART PRZEZ GRACZY. */
	  void exchangeTurn(final int x){
		  	System.out.println("Wywolana metoda exchangeTurn ["+x+"]");
		  
		  	if (PlayerStatus[x] && table.playersActivity[x]==1)	{
		  		hand[x].showHand(true);
		  		final JButton ChangeCards = new JButton("ChangeCards");
		    	ChangeCards.setBounds(0, 64, 120, 30);
				players[x].add(ChangeCards);
				final JButton NotChangeCards = new JButton("CHECK");
		    	NotChangeCards.setBounds(120, 64, 120, 30);
				players[x].add(NotChangeCards);
				ChangeCards.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if(table.playersActivity[x]==1) 
					  		hand[x].exchange(table.deck, table.hands[x], players[x].exchangeCards(hand[x]));
						table.hands[x].display();
						// hand[0].exchange(table.deck, table.hands[0], toExchange);
				  		hand[x].showHand(false);

						players[x].remove(ChangeCards); 
						players[x].remove(NotChangeCards);
						repaint();						
					  	//table.PlayerMove[x] = true;
					  	if(table.playersActivity[x]==1) 
							 endexchangeTurn(x);
						//if(x<table.numberOfActivePlayers-1)
						
						//System.out.println("Zakonczona metoda  exchangeTurn[" + x +"]");
					}
				});	
			
				NotChangeCards.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						players[x].remove(ChangeCards); 
						players[x].remove(NotChangeCards);
				  		hand[x].showHand(false);
				  		repaint();
						 table.PlayerMove[table.numberOfCurrentPlayer]=true;
						

						if(table.playersActivity[x]==1) 
							 endexchangeTurn(x);
						//System.out.println("Zakonczona metoda  exchangeTurn[" + x +"]");
					}
				});	
		  	}
		  	else {
		  		if(table.playersActivity[x]==1) 
			  		hand[x].exchange(table.deck, table.hands[x], players[x].exchangeCards(hand[x]));
			  		table.hands[x].display();
			  		hand[x].showHand(false);
			  		repaint();
					 table.PlayerMove[table.numberOfCurrentPlayer]=true;
						if(table.playersActivity[x]==1) 
							 endexchangeTurn(x);
		  	}
					//if(table.playersActivity[x]==1) 
		
		  
	  }
	  void endexchangeTurn(final int x){
			if(x<table.numberOfActivePlayers-1)
				exchangeTurn(x+1); 
			repaint();
  				  		//System.out.println("Zakonczona metoda  exchangeTurn[" + x +"]");

  	
  	System.out.println("Zakonczona metoda  exchangeTurn[" + x +"]");
  	if(x==table.numberOfActivePlayers-1 && (!table.playedAllIn)){
  		betTurn(0);second = true;}
  	else if (x==table.numberOfActivePlayers-1 && (table.playedAllIn))
  		evaluateTurn(); second= true;
 }
	  /** TURA WYSWIETLANIA WYNIKOW GRACZY. */
	  void evaluateTurn(){
	    for(i=0;i<table.numberOfPlayers;i++){
	    	hand[i].showHand(true);
		  if(table.playersActivity[i]==1){
		    System.out.print(table.players[i].getName() + " ");
		    table.hands[i].evaluate();
		    players[i].setText(""+table.hands[i].s);
		    table.hands[i].printEvaluate();
		    System.out.println("\n");
		  }
		}
	  }

	  /** TURA WYBIERANIA ZWYCIEZCY I ODDAWANIA MU STAWKI. */
	  void winnerTurn(){
	    int winner=(-1),draw=0;
	    for(int i=0;i<table.numberOfPlayers;i++){
		  if(table.playersActivity[i]==1){
		    if(winner==(-1)){winner=i;}
	        else if(table.hands[i].compareTo(table.hands[winner])==0){draw=1;}
	        else if(table.hands[i].compareTo(table.hands[winner])==1){draw=0; winner=i;}
		  }
		}
		if(winner==(-1)){draw=1;}
		if(draw==1){System.out.println("Draw!");}
		else{
	      for(int i=0;i<table.numberOfPlayers;i++){
		    if(winner!=i){
		      if(table.playersBets[i]>table.playersBets[winner]){
		    	  table.playersChips[winner]+=table.playersBets[winner];table.playersBets[i]-=table.playersBets[winner];
		    }
		      else{table.playersChips[winner]+=table.playersBets[i]; table.playersBets[i]=0;}
		    }
		  }
	      table.playersChips[winner]+=table.playersBets[winner]; table.playersBets[winner]=0;
		  for(int i=0;i<table.numberOfPlayers;i++){ // ODDAJEMY GRACZOM "NADMIAR" Z ICH STAWEK (JESLI GRALI DO KONCA). /
		    if(table.playersActivity[i]==1){table.playersChips[i]+=table.playersBets[i]; table.playersBets[i]=0;}
		  }
		  table.playersWins[winner]+=1;
		  System.out.println(players[winner].getName() + " wins!\n");
		}
		table.tablePool=0;
	  }

	  /** TURA WYSWIETLANIA RANKINGU. */
	  void displayRanking(){
	    for(int i=0;i<table.numberOfPlayers;i++){
		  System.out.println(players[i].getName());
		  System.out.println("Wins: " + table.playersWins[i]);
	      System.out.println("Chips: " + table.playersChips[i]);
		  System.out.println();
	      }
		}

	  /** TURA LICYTACJI. */
	  /** NUMERY AKCJI: 1-Check, 2-Bet, 3-Raise, 4-Call, 5-Fold, 6-All-In. */
	 void betTurn(int x){
		table.numberOfCurrentPlayer=x;
  		hand[x].showHand(true);
  		System.out.println("Wywolano betTurn[" + x +"]");
		//while((table.actionsPerformed<(table.numberOfActivePlayers))&&(table.numberOfActivePlayers>1)){
			  table.numberOfAction=0;
			  //LoadNumberOfAction(table.numberOfCurrentPlayer); //????
			  if(table.highestBid==0)
			  		{ players[x].betAction(this,table, true,false,true,true);}
				else if((table.highestBid!=0)&&(table.numberOfAllIns==0)&&(table.playersChips[table.numberOfCurrentPlayer]>(table.highestBid-table.playersBetsThisTurn[table.numberOfCurrentPlayer]))&&(table.playersChips[table.numberOfCurrentPlayer]>(table.highestBid-(table.playersBets[table.numberOfCurrentPlayer]-table.entryFee)+1)))
					{players[x].betAction(this,table,false,false,true,true);}
				else if((table.highestBid!=0)&&(table.numberOfAllIns==0)&&(table.playersChips[table.numberOfCurrentPlayer]>(table.highestBid-table.playersBetsThisTurn[table.numberOfCurrentPlayer]))&&(!(table.playersChips[table.numberOfCurrentPlayer]>(table.highestBid-(table.playersBets[table.numberOfCurrentPlayer]-table.entryFee)+1))))
					{players[table.numberOfCurrentPlayer].betAction(this,table,false,false,true,false);}
				else if((table.highestBid!=0)&&(table.numberOfAllIns==0)&&(!(table.playersChips[table.numberOfCurrentPlayer]>(table.highestBid-table.playersBetsThisTurn[table.numberOfCurrentPlayer]))))
					{players[table.numberOfCurrentPlayer].betAction(this,table,false,false,false,false);}
				else if((table.playersChips[table.numberOfCurrentPlayer]>table.highestBid)&&(table.playersChips[table.numberOfCurrentPlayer]>(table.highestBid+1)))
					{players[table.numberOfCurrentPlayer].betAction(this,table,false,true,true,true);}
				else if((table.playersChips[table.numberOfCurrentPlayer]>table.highestBid)&&(!(table.playersChips[table.numberOfCurrentPlayer]>(table.highestBid+1))))
					{players[table.numberOfCurrentPlayer].betAction(this,table,false,true,true,false);}
				else if(!(table.playersChips[table.numberOfCurrentPlayer]>table.highestBid))
					{players[table.numberOfCurrentPlayer].betAction(this,table,false,true,false,false);}
				table.playersBets[x]+=table.playersBetsThisTurn[x];
			
	 //   if(table.numberOfCurrentPlayer<3){betTurn(x+1);}
		  //else{betTurn(0);}
	 //   }
	
	  }
	 void endbetTurn(int x){
			refreshRank();
			repaint();
			hand[x].showHand(false);
			System.out.println("Zakonczono betTurn[" + x +"]");
			if(table.numberOfCurrentPlayer<3 && !second){betTurn(x+1);}
			else if(table.numberOfCurrentPlayer<3 && second){betTurn(x+1);}
			else if(table.numberOfCurrentPlayer >1 && !second  ){
				 exchangeTurn(0);}
			else if(table.numberOfActivePlayers>1 && second  ){
				 evaluateTurn();
				 winnerTurn();
			     refreshRank();
				displayRanking();
				for (i=0;i<table.numberOfActivePlayers;i++)
				hand[i].showHand(true);
			}
			
	 }
	 	
	
	/*String LoadNameOfPlayer()	{
		String result;
		final JTextField txt = new JTextField("First player name");
		txt.setBounds(160, 192, 80, 32);
		getContentPane().add(textField);
		txt.setColumns(10);
		final JButton OK = new JButton("OK");
		OK.setBounds(184, 224, 32, 32);
		getContentPane().add(OK);
		result = txt.getText();
		OK.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				getContentPane().remove(txt);
				repaint();
				getContentPane().remove(OK);
				repaint();
			}
		});
		
		return result;
	}*/
	 // private void entryFeeTurn(){
		//	for(int i=0;i<table.numberOfPlayers;i++){
	//		  if(table.playersActivity[i]==1){playersBets[i]+=entryFee; tablePool+=entryFee; playersChips[i]-=entryFee;}
	//		}
	//	  }
	 void createRank(){
			for (i = 0; i < table.numberOfPlayers; i++){
				
				PlayerName[i] = new JTextArea();
				PlayerName[i].setBackground(background);
				PlayerName[i].setText(""+table.players[i].getName() + "        ");
				PlayerName[i].setBounds(210, 190+32*i, 60, 16);
				getContentPane().add(PlayerName[i]);
				CashPlayer[i] = new JTextArea();
				CashPlayer[i].setBackground(background);
				CashPlayer[i].setText(""+table.playersChips[2]);
				CashPlayer[i].setBounds(270, 190+32*i, 120, 16);
				getContentPane().add(CashPlayer[i]);
				}
	 }
	  void refreshRank()	{
			for (i = 0; i < table.numberOfPlayers; i++){
				PlayerName[i].setText(""+table.players[i].getName() + "        ");
				CashPlayer[i].setText(""+table.playersChips[i]);
				tablePoolGui.setText(""+table.tablePool);
				}  
	  }
	  public void resetMoves(){
		  for (i=0;i<table.numberOfActivePlayers;i++)
				table.PlayerMove[i]=false; //0-entryFeeTurn,1-betTurn, 2-exchangeTurn,3-evaluate turn;4-winner turn;5-displayranking
			
	  }
	  
	  public void refreshTable(){
		  if(table.enoughPlayers){
			  repaint();
				 resetMoves();
			     refreshRank();
			}
	  }
	  public void nextGame(){
		  if(table.enoughPlayers){
			  w.manySec(1);
			  //refreshTable();
			 // final DeckGui D = new DeckGui(table.deck);

			  createHands(); repaint();
			  for (i=0;i<table.numberOfActivePlayers;i++)
					hand[i].showHand(false);
				 resetMoves(); //repaint();
			     refreshRank();
			     betTurn(0);
			     refreshRank();
				
			}
	  }
	/**
	 * Konstruktor Table GUI
	 */
	public TableGui(int NumberOfPlayers, int NumberOfHumanPlayers, int NumberOfChips, int EntryFee) {
		getContentPane().setVisible(true);
		setResizable(false);
		
		getContentPane().setBackground(background);
		getContentPane().setSize(new Dimension(640, 480));
		getContentPane().setMinimumSize(new Dimension(640, 480));
		getContentPane().setMaximumSize(new Dimension(640, 480));
		setBounds(100, 100,640, 480);
		setTitle("POKER :)");
		getContentPane().setForeground(new Color(245, 245, 245));
		getContentPane().setLayout(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(true);
		getContentPane().setLayout(null);
		
		
		table = new Table();
		resetAllSettings();
		/** WCZYTYWANIE ILOSCI GRACZY I ILOSCI GRACZY LUDZI */
		table.numberOfPlayers = NumberOfPlayers;
		System.out.println("Liczba wszystkich graczy " + table.numberOfPlayers);
		table.numberOfHumanPlayers = NumberOfHumanPlayers;
		System.out.println("Liczba humanow " + table.numberOfHumanPlayers);
		table.numberOfChips = NumberOfChips;
		
		/** WCZYTYWANIE ILOSCI ZETONOW I WYSOKOSCI WPISOWEGO. */
		table.entryFee = EntryFee;
		table.numberOfChips = NumberOfChips;
		System.out.println("Liczba chip na start " + table.numberOfChips);
		System.out.println("Stawka wejsciowa " + table.entryFee);
		   /** **************************************. */
		createPlayers();
		
		System.out.println("NumberOfPlayers: " +table.numberOfPlayers);
		System.out.println("NumberOfHumanPlayers: " +table.numberOfPlayers);
		checkPlayers();
		table.numberOfActivePlayers=table.numberOfPlayers;
		//0-entryFeeTurn,1-betTurn, 2-exchangeTurn,3-evaluate turn;4-winner turn;5-displayranking

		tablePoolGui = new JTextArea();
		tablePoolGui.setBackground(background);
		tablePoolGui.setText(""+table.tablePool);
		tablePoolGui.setBounds(280, 201, 48, 16);
		getContentPane().add(tablePoolGui);
		
		//w.manySec(5);
		 createRank();
		 entryFeeTurn();
		//while(table.enoughPlayers){
			nextGame();
			 
		//}
		
	}
}
